﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using LightCAD.MathLib;
namespace LightCAD.MathLib
{
    public class Arc2d : Curve2d
    {
        [JsonInclude]
        public Vector2 Center;
        public double Radius { get; set; }
        public double StartAngle { get; set; }
        public double EndAngle { get; set; }
        public Vector2 Startp { get; set; }
        public Vector2 Endp { get; set; }
        public Vector2 Midp { get; set; }
        public bool IsClockwise { get; set; } = false;
        public override bool IsClosed { get => base.IsClosed; }
        public Arc2d()
        {
            this.IsClosed = false;
            this.Type = Curve2dType.Arc2d;
        }

        public override void Copy(Curve2d src)
        {
            var arc = src as Arc2d;
            this.Center = arc.Center.Clone();
            this.Radius = arc.Radius;
            this.StartAngle = arc.StartAngle;
            this.EndAngle = arc.EndAngle;
            this.Name = arc.Name;
            this.IsClockwise = arc.IsClockwise;
        }
        public override Curve2d Clone()
        {
            var newObj = new Arc2d();
            newObj.Copy(this);
            return newObj;
        }

        /// <summary>
        /// 获取坐标
        /// </summary>
        /// <param name="pt">圆心</param>
        /// <param name="ang">角度</param>
        /// <param name="dst">半径</param>
        /// <returns></returns>
        public static Vector2 GetPointByArc(Vector2 pt, double ang, double dst)
        {
            ang = FixAngle(ang);
            return new Vector2((Cos(ang) * dst) + pt.X, (Sin(ang) * dst) + pt.Y);
        }
        public static bool AreEqual(double val1, double val2, double eq)
        {
            return (Math.Abs((double)(val1 - val2)) < eq);
        }
        public static double Sin(double angleRadius)
        {
            double eq = 1E-07;
            if (AreEqual(angleRadius, 0.0, eq))
            {
                return 0.0;
            }
            if (AreEqual(angleRadius, 1.5707963267948, eq))
            {
                return 1.0;
            }
            if (AreEqual(angleRadius, 3.1415926535898, eq))
            {
                return 0.0;
            }
            if (AreEqual(angleRadius, 4.7123889803844, eq))
            {
                return -1.0;
            }
            if (AreEqual(angleRadius, 6.2831853071796, eq))
            {
                return 0.0;
            }
            return Math.Sin(angleRadius);
        }
        public static double Cos(double angleRadius)
        {
            double eq = 1E-07;
            if (AreEqual(angleRadius, 0.0, eq))
            {
                return 1.0;
            }
            if (AreEqual(angleRadius, 1.5707963267948, eq))
            {
                return 0.0;
            }
            if (AreEqual(angleRadius, 3.1415926535898, eq))
            {
                return -1.0;
            }
            if (AreEqual(angleRadius, 4.7123889803844, eq))
            {
                return 0.0;
            }
            if (AreEqual(angleRadius, 6.2831853071796, eq))
            {
                return 1.0;
            }
            return Math.Cos(angleRadius);
        }
        public static double FixAngle(double inangle)
        {
            double eq = 1E-06;
            if (AreEqual(inangle, 6.2831853071796, eq))
            {
                return 6.2831853071796;
            }
            double num2 = inangle;
            num2 = num2 % 6.2831853071796;
            if (num2 > (6.2831853071796 + eq))
            {
                num2 -= 6.2831853071796;
            }
            if ((num2 + eq) < 0.0)
            {
                num2 += 6.2831853071796;
            }
            if (AreEqual(num2, 0.0, eq))
            {
                return 0.0;
            }
            if (AreEqual(num2, 1.5707963267948, eq))
            {
                return 1.5707963267948;
            }
            if (AreEqual(num2, 3.1415926535898, eq))
            {
                return 3.1415926535898;
            }
            if (AreEqual(num2, 4.7123889803844, eq))
            {
                return 4.7123889803844;
            }
            if (AreEqual(num2, 6.2831853071796, eq))
            {
                return 6.2831853071796;
            }
            return num2;
        }
        public static double Distance2D(Vector2 P, Vector2 pt)
        {
            return Math.Sqrt(((P.X - pt.X) * (P.X - pt.X)) + ((P.Y - pt.Y) * (P.Y - pt.Y)));
        }
        public static double GetAngle(Vector2 p1, Vector2 p2)
        {
            if (AreEqual(Distance2D(p1, p2), 0.0, 1E-08))
            {
                return 0.0;
            }
            return FixAngle(Math.Atan2(p2.Y - p1.Y, p2.X - p1.X));
        }
        public static void getmidp()
        {
            //            import math

            //# 圆弧的起始和结束坐标
            //startX = 1
            //startY = 2
            //endX = 4
            //endY = 6

            //# 圆弧半径
            //radius = 5

            //# 圆心坐标
            //centerX = (startX + endX) / 2
            //centerY = (startY + endY) / 2

            //# 计算起始角度和结束角度（以x轴正方向为0度）
            //angle_start = math.atan2(startY - centerY, startX - centerX)
            //angle_end = math.atan2(endY - centerY, endX - centerX)

            //# 计算中间角度（取两个角度的平均值）
            //angle_mid = (angle_start + angle_end) / 2

            //# 计算中间点坐标
            //midX = centerX + radius * math.cos(angle_mid)
            //midY = centerY + radius * math.sin(angle_mid)

            //print("The midpoint of the arc:")
            //print("X:", midX)
            //print("Y:", midY)

        }

        public static Box2 GetArcBox(Vector2 center, double radius, double startAngle, double endAngle)
        {
            Box2 box = new Box2();
            //if (IsCircle(StartAngle, EndAngle))
            //{
            //    box.AddPoint(Center);
            //    box.AddWidth(Radius);
            //    return box;
            //}
            Vector2 pt = GetPointByArc(center, startAngle, radius);
            Vector2 point2 = GetPointByArc(center, endAngle, radius);
            Vector2 point3 = new Vector2(pt.X, pt.Y);
            Vector2 point4 = new Vector2(point2.X, point2.Y);
            Vector2 point5 = new Vector2(pt.X, pt.Y);
            Vector2 point6 = new Vector2(pt.X, pt.Y);
            Vector2 point7 = new Vector2(pt.X, pt.Y);
            Vector2 point8 = new Vector2(pt.X, pt.Y);
            double[] numArray = new double[] { 0.0, 1.5707963267948, 3.1415926535898, 4.7123889803844 };
            Vector2 point9 = GetPointByArc(center, numArray[0], radius);
            Vector2 point10 = GetPointByArc(center, numArray[1], radius);
            Vector2 point11 = GetPointByArc(center, numArray[2], radius);
            Vector2 point12 = GetPointByArc(center, numArray[3], radius);
            double num = startAngle;
            double num2 = endAngle;
            num2 -= num;
            numArray[0] -= num;
            numArray[1] -= num;
            numArray[2] -= num;
            numArray[3] -= num;
            num = 0.0;
            //if (num2 < 0.0)
            //{
            //    num2 += 6.2831853071796;
            //}
            //if (numArray[0] < 0.0)
            //{
            //    numArray[0] += 6.2831853071796;
            //}
            //if (numArray[1] < 0.0)
            //{
            //    numArray[1] += 6.2831853071796;
            //}
            //if (numArray[2] < 0.0)
            //{
            //    numArray[2] += 6.2831853071796;
            //}
            //if (numArray[3] < 0.0)
            //{
            //    numArray[3] += 6.2831853071796;
            //}
            //if ((numArray[0] > num) && (numArray[0] < num2))
            //{
            //    point5.CopyFrom(point9); 
            //}
            //if ((numArray[1] > num) && (numArray[1] < num2))
            //{
            //    point6.CopyFrom(point10);
            //}
            //if ((numArray[2] > num) && (numArray[2] < num2))
            //{
            //    point7.CopyFrom(point11);
            //}
            //if ((numArray[3] > num) && (numArray[3] < num2))
            //{
            //    point8.CopyFrom(point12);
            //}
            //box.a(point3);
            //box.AddPoint(point4);
            //box.AddPoint(point5);
            //box.AddPoint(point6);
            //box.AddPoint(point7);
            //box.AddPoint(point8);
            return box;
        }
        public static bool ArcFrom3Points(Vector2 sp, Vector2 ep, Vector2 mp, out Vector2 cen, out double rad, out double sa, out double ea)
        {
            Vector2 pt = new Vector2();
            Vector2 point2 = new Vector2();
            double ang = GetAngle(sp, mp) + 1.5707963267948;
            double num2 = GetAngle(sp, ep) + 1.5707963267948;
            pt.X = (sp.X / 2.0) + (mp.X / 2.0);
            pt.Y = (sp.Y / 2.0) + (mp.Y / 2.0);
            point2.X = (sp.X / 2.0) + (ep.X / 2.0);
            point2.Y = (sp.Y / 2.0) + (ep.Y / 2.0);
            Vector2 point3 = GetPointByArc(pt, ang, 100.0);
            Vector2 point4 = GetPointByArc(point2, num2, 100.0);
            double num3 = num2 - ang;
            if (num3 < 0.0)
            {
                num3 += 6.2831853071796;
            }
            cen = new Vector2();
            IntersectionLL2D(pt, point3, point2, point4, out cen);
            rad = Distance2D(cen, sp);
            if (num3 > 3.1415926535898)
            {
                sa = GetAngle(cen, ep);
                ea = GetAngle(cen, sp);
            }
            else
            {
                sa = GetAngle(cen, sp);
                ea = GetAngle(cen, ep);
            }
            return true;
        }
        public static bool PointInArc(Vector2 mp, Vector2 sp, Vector2 ep, Vector2 cp)
        {
            var ms = GeoUtils.IsTopInLine(cp, sp, mp);
            var me = GeoUtils.IsTopInLine(cp, ep, mp);
            var sm = GeoUtils.IsTopInLine(cp, ep, sp);
            //   bool zh = false;
            if ((ms == me && sm < 0) || (me > 0 && ms < 0))
            {
                return true;

            }
            else return false;
        }
        public static int IntersectionLL2D(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, out Vector2 retpt)
        {
            double x = p1.X;
            double num2 = p2.X;
            double num3 = p3.X;
            double num4 = p4.X;
            double y = p1.Y;
            double num6 = p2.Y;
            double num7 = p3.Y;
            double num8 = p4.Y;
            double num9 = (((x + num2) + num3) + num4) / 4.0;
            double num10 = (((y + num6) + num7) + num8) / 4.0;
            x -= num9;
            num2 -= num9;
            num3 -= num9;
            num4 -= num9;
            y -= num10;
            num6 -= num10;
            num7 -= num10;
            num8 -= num10;
            double num11 = num8 - num7;
            double num12 = num3 - num4;
            double num13 = num6 - y;
            double num14 = x - num2;
            double num15 = (num11 * num14) - (num13 * num12);
            retpt = new Vector2();
            retpt.X = 0;
            retpt.Y = 0;
            if (AreEqual(num15, 0.0, 1E-06))
            {
                return 0;
            }
            double num16 = (num4 * num7) - (num3 * num8);
            double num17 = (num2 * y) - (x * num6);
            double num18 = (num12 * num17) - (num14 * num16);
            double num19 = (num13 * num16) - (num11 * num17);
            retpt.X = (num18 / num15) + num9;
            retpt.Y = (num19 / num15) + num10;

            return 1;
        }

        public static double GetDegreesByTwoLine(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;

            // 计算线段的向量表示
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x4 - x3;
            double v2y = y4 - y3;

            // 计算向量的内积
            double dotProduct = v1x * v2x + v1y * v2y;

            // 计算向量的长度
            double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
            double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);

            // 计算夹角余弦值
            double cosine = dotProduct / (magnitudeV1 * magnitudeV2);

            // 将夹角余弦值转换为角度
            double angleRadians = Math.Acos(cosine);
            double angleDegrees = angleRadians * 180 / Math.PI;
            return angleDegrees;
        }

        public override Curve2d Translate(Vector2 offset)
        {
            this.Center.Add(offset);
            return this;
        }

        public override Curve2d RotateAround(Vector2 basePoint, double angle)
        {
            this.Center.RotateAround(basePoint, angle);
            this.StartAngle += angle;
            this.EndAngle += angle;
            return this;
        }

        public override Curve2d Mirror(Vector2 axisStart, Vector2 axisDir)
        {
            this.Center.Mirror(axisStart, axisDir);
            this.IsClockwise = !this.IsClockwise;
            var divAngle = axisDir.Angle();
            if (divAngle > MathUtil.Pi)
                divAngle -= MathUtil.Pi;
            this.StartAngle -= 2 * (this.StartAngle - divAngle);
            this.EndAngle -= 2 * (this.EndAngle - divAngle);
            return this;
        }
        public override Curve2d Reverse()
        {
            this.IsClockwise = !this.IsClockwise;
            var temp = this.StartAngle;
            this.StartAngle = this.EndAngle;
            this.EndAngle = temp;
            return this;
        }
        public override Vector2[] GetPoints(int div = 5, double scaleInFuture = 1)
        {
            if (div <= 0)
            {
                var angle = (this.EndAngle - this.StartAngle);
                if (angle <= 0)
                    angle += Utils.TwoPI;
                div = (int)Math.Ceiling(this.Radius * scaleInFuture * Utils.TwoPI / angle * 0.5);
            }
            var result = new Vector2[div + 1];
            for (int i = 0; i <= div; i++)
            {
                var delta = (double)i / div;
                result[i] = Ellipse2d.getEllipsePoint(this.Center, this.Radius, this.Radius, this.StartAngle, this.EndAngle, 0, this.IsClockwise, delta);
            }
            return result;
        }
        public override Curve3d ToCurve3d()
        {
            return new Arc3d(this.Center.ToVector3(), this.Radius, this.StartAngle, this.EndAngle, this.IsClockwise);
        }
        /// <summary>
        /// 获取圆弧圆心
        /// </summary>
        /// <param name="startp"></param>
        /// <param name="midp"></param>
        /// <param name="endp"></param>
        /// <returns></returns>
        public static Vector2 GetCenter(Vector2 startp, Vector2 midp, Vector2 endp)
        {
            Vector2 Center = new Vector2();
            double a = startp.X - midp.X;
            double b = startp.Y - midp.Y;
            double c = startp.X - endp.X;
            double d = startp.Y - endp.Y;
            double e = ((startp.X * startp.X - midp.X * midp.X) - (midp.Y * midp.Y - startp.Y * startp.Y)) / 2;
            double f = ((startp.X * startp.X - endp.X * endp.X) - (endp.Y * endp.Y - startp.Y * startp.Y)) / 2;

            // 圆心位置 
            var x = (e * d - b * f) / (a * d - b * c);
            var y = (a * f - e * c) / (a * d - b * c);
            Center.X = x;
            Center.Y = y;
            return Center;
        }
        /// <summary>
        /// 获得圆弧的中点
        /// </summary>
        public Vector2 Getmidpoint()
        {
            var sage = this.StartAngle * 180 / Math.PI;
            var eage = this.EndAngle * 180 / Math.PI;
            double moveAngle = eage - sage;
            if (moveAngle < 0)
            {
                moveAngle += 360;
            }
            double midAngle = (moveAngle / 2);  //需要旋转的角度
            var matrix3 = Matrix3.Rotate(midAngle, this.Center); //围绕圆心旋转
            var mp = matrix3.MultiplyPoint(this.Startp); //旋转矩阵是逆时针旋转
            return new Vector2(mp.X, mp.Y);
        }


        public static Arc2d CreateARC(Vector2 sp, Vector2 mp, Vector2 ep)
        {
            Arc2d arc2D = new Arc2d();
            arc2D.Center = GetCenter(sp, mp, ep);
            arc2D.Radius = Vector2.Distance(sp, arc2D.Center);
            double Degrees, smidAngle, emidAngle;
            arc2D.StartAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(sp.X, sp.Y)); //计算圆弧的起始角度
            arc2D.EndAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(ep.X, ep.Y));
            if (GeoUtils.IsTopInLine(arc2D.Center, sp, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
            {
                arc2D.StartAngle = 360 - arc2D.StartAngle;
            }
            if (GeoUtils.IsTopInLine(arc2D.Center, ep, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
            {
                arc2D.EndAngle = 360 - arc2D.EndAngle;
            }
            var ms = GeoUtils.IsTopInLine(arc2D.Center, sp, mp);
            var me = GeoUtils.IsTopInLine(arc2D.Center, ep, mp);
            var sm = GeoUtils.IsTopInLine(arc2D.Center, ep, sp);
            if ((ms == me && sm < 0) || (me > 0 && ms < 0))
            {
                arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
                arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
                arc2D.Startp = sp;
                arc2D.Endp = ep;


            }
            else
            {

                Degrees = arc2D.StartAngle;
                arc2D.Startp = ep;
                arc2D.Endp = sp;
                arc2D.StartAngle = arc2D.EndAngle / 180 * Math.PI;
                arc2D.EndAngle = Degrees / 180 * Math.PI;
            }

            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }


        public static Arc2d CreatePCE(Vector2 sp, Vector2 cp, Vector2 ep)
        {
            Arc2d arc2D = new Arc2d();
            arc2D.Center = cp;
            arc2D.StartAngle = (Math.Atan2(sp.Y - cp.Y, sp.X - cp.X) * 180 / Math.PI);
            arc2D.EndAngle = (Math.Atan2(ep.Y - cp.Y, ep.X - cp.X) * 180 / Math.PI);
            arc2D.Radius = Vector2.Distance(arc2D.Center, sp);
            if (arc2D.StartAngle < 0)
            {
                arc2D.StartAngle += 360;
            }
            if (arc2D.EndAngle < 0)
            {
                arc2D.EndAngle += 360;
            }
            arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
            arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            arc2D.Startp = sp;
            arc2D.Endp = ep;  //求端点
            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }

        public static Arc2d CreatePCA(Vector2 sp, Vector2 cp, Vector2 ap)
        {
            Arc2d arc2D = new Arc2d();
            arc2D.Center = cp;
            arc2D.StartAngle = (Math.Atan2(sp.Y - cp.Y, sp.X - cp.X) * 180 / Math.PI);
            double moveAngle = (Math.Atan2(ap.Y - cp.Y, ap.X - cp.X) * 180 / Math.PI);
            arc2D.Radius = Vector2.Distance(arc2D.Center, sp);
            arc2D.EndAngle = arc2D.StartAngle + moveAngle; //端点角度
            if (arc2D.EndAngle > 360)
            {
                arc2D.EndAngle = arc2D.EndAngle - 360;
            }
            arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
            arc2D.Startp = sp;
            arc2D.Endp = new Vector2(arc2D.Center.X + arc2D.Radius * Math.Cos(arc2D.EndAngle), arc2D.Center.Y + arc2D.Radius * Math.Sin(arc2D.EndAngle));  //求端点
            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }
        public static Arc2d CreatePCL(Vector2 sp, Vector2 cp, Vector2 ap)
        {
            Arc2d arc2D = new Arc2d();
            arc2D.Center = cp;
            arc2D.Radius = Vector2.Distance(cp, sp);//计算半径
            double chordLength = Vector2.Distance(sp, ap); //计算弦长
            double chordAngleRadians = (2 * Math.Asin(chordLength / (2 * arc2D.Radius))) * 180 / Math.PI;  //计算弦角度
            arc2D.StartAngle = (Math.Atan2(sp.Y - cp.Y, sp.X - cp.X) * 180 / Math.PI);
            if (arc2D.StartAngle < 0)
            {
                arc2D.StartAngle += 360;
            }
            arc2D.EndAngle = (arc2D.StartAngle + chordAngleRadians) % 360;
            arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
            arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            if (arc2D.EndAngle < 0)
            {
                arc2D.EndAngle += 360;
            }
            arc2D.Startp = sp;
            arc2D.Endp = new Vector2(arc2D.Center.X + arc2D.Radius * Math.Cos(arc2D.EndAngle), arc2D.Center.Y + arc2D.Radius * Math.Sin(arc2D.EndAngle));  //求端点
            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }
        public static Arc2d CreatePEA(Vector2 sp, Vector2 mp, Vector2 ep)
        {
            Arc2d arc2D = new Arc2d();
            double angle = (Math.Atan2(ep.Y - sp.Y, ep.X - sp.X) * 180 / Math.PI); //圆心旋转角度，落点的水平角
            double angle1 = (Math.Atan2(mp.Y - sp.Y, mp.X - sp.X) * 180 / Math.PI); //弦长与x轴的夹角
            double midX = (sp.X + mp.X) / 2;//计算圆弧的中点坐标
            double midY = (sp.Y + mp.Y) / 2;
            arc2D.Center = new Vector2();
            if (angle < 0)
            {
                angle += 360;
            }
            double radius = 0;
            if (angle > 180)
            {
                double angle3 = 360 - angle;
                if (angle1 < 0)
                {
                    angle1 += 360;
                }
                double chordLength = Vector2.Distance(sp, mp);  //起点和终点之间的距离 也就是弦长
                radius = (chordLength / 2) / Math.Sin((angle3 / 2) * Math.PI / 180);        //半径
                double height = Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(chordLength / 2, 2));
                arc2D.Center.X = midX + height * Math.Sin((angle1) * Math.PI / 180);
                arc2D.Center.Y = midY - height * Math.Cos((angle1) * Math.PI / 180);
            }
            if (angle <= 180)
            {
                double chordLength = Vector2.Distance(sp, mp);  //起点和终点之间的距离 也就是弦长
                radius = (chordLength / 2) / Math.Sin((angle / 2) * Math.PI / 180);        //半径
                double height = Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(chordLength / 2, 2));
                arc2D.Center.X = midX - height * Math.Sin(angle1 * Math.PI / 180);
                arc2D.Center.Y = midY + height * Math.Cos(angle1 * Math.PI / 180);
            }
            var startAngle = (Math.Atan2(sp.Y - arc2D.Center.Y, sp.X - arc2D.Center.X) * 180 / Math.PI);
            if (startAngle < 0)
            {
                startAngle += 360;
            }
            var endAngle = startAngle + angle;
            if (endAngle > 360)
            {
                endAngle -= 360;
            }
            startAngle = startAngle * Math.PI / 180;
            endAngle = endAngle * Math.PI / 180;
            //逻辑模型
            arc2D.IsClockwise = false;
            arc2D.StartAngle = startAngle;
            arc2D.EndAngle = endAngle;
            arc2D.Center = arc2D.Center;
            arc2D.Radius = radius;
            arc2D.Startp = sp;
            arc2D.Endp = new Vector2(arc2D.Center.X + arc2D.Radius * Math.Cos(arc2D.EndAngle), arc2D.Center.Y + arc2D.Radius * Math.Sin(arc2D.EndAngle));  //求端点
            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }
        public static Arc2d CreatePED(Vector2 sp, Vector2 mp, Vector2 ep)
        {
            double angle = GetDegreesByTwoLine(sp, mp, sp, ep);  //相切线和弦长线之间的夹角B
            bool clockwise = Vector2.Clockwise(sp, mp, ep);
            if (!clockwise)  //如果是顺时针
            {
                Arc2d arc2D = CreatePEDHelp(mp, sp, angle);
                arc2D.Startp = mp;
                arc2D.Endp = new Vector2(arc2D.Center.X + arc2D.Radius * Math.Cos(arc2D.EndAngle), arc2D.Center.Y + arc2D.Radius * Math.Sin(arc2D.EndAngle));  //求端点
                arc2D.Midp = arc2D.Getmidpoint();
                return arc2D;
            }
            else
            {
                Arc2d arc2D = CreatePEDHelp(sp, mp, angle);
                arc2D.Startp = sp;
                arc2D.Endp = new Vector2(arc2D.Center.X + arc2D.Radius * Math.Cos(arc2D.EndAngle), arc2D.Center.Y + arc2D.Radius * Math.Sin(arc2D.EndAngle));  //求端点
                arc2D.Midp = arc2D.Getmidpoint();
                return arc2D;
            }
        }
        public static Arc2d CreatePEDHelp(Vector2 sp, Vector2 mp, double angle)
        {
            Arc2d arc2D = new Arc2d();
            double chordLength = Vector2.Distance(mp, sp) / 2; //计算弦长的一半
            var mid = new Vector2();
            mid.X = sp.X;
            mid.Y = sp.Y + chordLength;
            double radius = chordLength / Math.Sin(angle * Math.PI / 180);
            arc2D.Center = new Vector2();
            arc2D.Center.X = mid.X - radius * Math.Cos(angle * Math.PI / 180);
            arc2D.Center.Y = mid.Y;
            double angle2 = GetDegreesByTwoLine(sp, mp, sp, mid);  //弦长与y轴的夹角（需要旋转的角度）
            if (angle2 < 0)
            {
                angle2 += 360;
            }
            if (GeoUtils.IsTopInLine(sp, mid, mp) > 0)
            {
                var matrix3 = Matrix3.Rotate((360 - angle2), sp);
                arc2D.Center = matrix3.MultiplyPoint(arc2D.Center);
            }
            else if (GeoUtils.IsTopInLine(sp, mid, mp) == 0)
            {
                if (mp.Y < sp.Y)
                {
                    var matrix3 = Matrix3.Rotate(180, sp);
                    arc2D.Center = matrix3.MultiplyPoint(arc2D.Center);
                }
            }
            else
            {
                var matrix3 = Matrix3.Rotate(angle2, sp);
                arc2D.Center = matrix3.MultiplyPoint(arc2D.Center);
            }
            arc2D.StartAngle = (Math.Atan2(sp.Y - arc2D.Center.Y, sp.X - arc2D.Center.X)) * 180 / Math.PI;
            if (arc2D.StartAngle < 0)
            {
                arc2D.StartAngle += 360;
            }
            arc2D.EndAngle = (Math.Atan2(mp.Y - arc2D.Center.Y, mp.X - arc2D.Center.X)) * 180 / Math.PI;
            if (arc2D.EndAngle < 0)
            {
                arc2D.EndAngle += 360;
            }
            arc2D.IsClockwise = false;
            arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
            arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            arc2D.Center = arc2D.Center;
            arc2D.Radius = radius;
            return arc2D;
        }
        public static Arc2d CreatePER(Vector2 sp, Vector2 mp, Vector2 ep)
        {
            Arc2d arc2D = new Arc2d();
            //bool clockwise = Vector2.Clockwise(sp, mp, ep);
            //if (clockwise)  //如果是顺时针
            //{
            //    var point =new Vector2();
            //    point = sp;
            //    sp = mp;
            //    mp = point;
            //}
            double radius = Vector2.Distance(ep, mp);   //计算半径
            arc2D.Center = new Vector2();
            double angle = Math.Atan2(mp.Y - sp.Y, mp.X - sp.X);
            //计算圆弧的中点坐标
            double midX = (sp.X + mp.X) / 2;
            double midY = (sp.Y + mp.Y) / 2;
            double chordLength = Math.Sqrt(Math.Pow(mp.X - sp.X, 2) + Math.Pow(mp.Y - sp.Y, 2)) / 2;  //计算弦长的一半
            double height = Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(chordLength, 2));
            arc2D.Center.X = midX - height * Math.Sin(angle);
            arc2D.Center.Y = midY + height * Math.Cos(angle);
            arc2D.StartAngle = (Math.Atan2(sp.Y - arc2D.Center.Y, sp.X - arc2D.Center.X)) * 180 / Math.PI;
            if (arc2D.StartAngle < 0)
            {
                arc2D.StartAngle += 360;
            }
            arc2D.EndAngle = (Math.Atan2(mp.Y - arc2D.Center.Y, mp.X - arc2D.Center.X)) * 180 / Math.PI;
            if (arc2D.EndAngle < 0)
            {
                arc2D.EndAngle += 360;
            }
            arc2D.IsClockwise = false;
            arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
            arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            arc2D.Center = arc2D.Center;
            arc2D.Radius = radius;
            arc2D.Startp = sp;
            arc2D.Endp = mp;  //求端点
            arc2D.Midp = arc2D.Getmidpoint();
            return arc2D;
        }

    }
}